package com.shuqi.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.message.BasicNameValuePair;

import android.content.Context;
import android.text.TextUtils;

import com.shuqi.common.utils.Log4an;
import com.shuqi.common.utils.Util;
import com.shuqi.database.dao.impl.BookInfoDao;
import com.shuqi.database.dao.impl.BookMarkInfoDao;
import com.shuqi.database.model.BookInfo;
import com.shuqi.database.model.BookMarkInfo;
import com.shuqi.database.model.UserInfo;
import com.shuqi.interfaces.EventTypeConstants;
import com.shuqi.model.bean.CheckBookUpdateInfo;
import com.shuqi.model.manager.MyAccountManager;
import com.shuqi.model.net.HttpRequest;
import com.shuqi.model.net.UrlManager;
import com.shuqi.model.net.listener.HttpRequestListener;
import com.shuqi.model.parse.parser.CheckBooksUpdateSMPaser;
import com.shuqi.model.parse.parser.CheckBooksUpdateSQPaser;

/***
 * 检查书签书籍的更新 <br>
 * 1.获取书签列表 <br>
 * 2.组织成对应的参数 <br>
 * 3.联网请求得到有更新的书籍列表 <br>
 * 4.更新数据库
 */
public class CheckBookMarkUpdate {
    private static final String logTag = "CheckBookMarkUpdate";

    /** 检查书籍更新：检查书旗书签的个数（按时间排序） */
    private static final int CHECKMARKNUM_SHUQI = 50;
    /** 检查书籍更新：检查神马书签的个数（按时间排序） */
    private static final int CHECKMARKNUM_SHENMA = 50;

    /** 检查更新结果类型：没有书签 */
    public static final int TYPE_CHECKRESULT_NOMARK = 0;
    /** 检查更新结果类型：网络失败 */
    public static final int TYPE_CHECKRESULT_NETERROR = 1;
    /** 检查更新结果类型：没有更新 */
    public static final int TYPE_CHECKRESULT_NONE = 2;
    /** 检查更新结果类型：有书籍更新 */
    public static final int TYPE_CHECKRESULT_HASUPDATE = 3;
    /** 检查更新结果类型：正在检查更新 */
    public static final int TYPE_CHECKRESULT_ISCHECKING = 4;

    /** 是否有更新的书籍：默认false */
    private boolean hasUpdate = false;
    /** 是否正在检查书籍更新：默认false */
    private boolean isChecking = false;
    
    private int shuqiCheckType = TYPE_CHECKRESULT_NONE;
    private int yisouCheckType = TYPE_CHECKRESULT_NONE;
    
    private static CheckBookMarkUpdate checkBookMarkUpdate;
    private CheckBookMarkUpdate(){}
    public static CheckBookMarkUpdate getInstance(){
        if(checkBookMarkUpdate == null){
            checkBookMarkUpdate = new CheckBookMarkUpdate();
        }
        return checkBookMarkUpdate;
    }

    public void checkBookMarksUpdate(final Context applicationContext,
            final CheckBookMarkUpdateLinstener linstener) {
        if (isChecking || applicationContext == null) {
            linstener.onFinish(false, TYPE_CHECKRESULT_ISCHECKING, null);
            return;
        }
        isChecking = true;
        hasUpdate = false;
        shuqiCheckType = TYPE_CHECKRESULT_NONE;
        yisouCheckType = TYPE_CHECKRESULT_NONE;
        
        UserInfo userInfo = MyAccountManager.getInstance(applicationContext);
        if (userInfo != null) {
            Log4an.i(logTag, "检查更新，用户ID：" + userInfo.getUserId());
        }
        final List<CheckBookUpdateInfo> fList = new ArrayList<CheckBookUpdateInfo>();
        if (!MyAccountManager.isGuestUser(userInfo)) {
            final String userId = userInfo.getUserId();
            // 2.书旗检查完毕后，再执行神马的书签检查更新
            final CheckLinstener linstener2 = new CheckLinstener() {
                @Override
                public void onFinish(int resultType, List<CheckBookUpdateInfo> list) {
                    yisouCheckType = resultType;
                    if (list != null && list.size() > 0
                            && resultType == CheckBookMarkUpdate.TYPE_CHECKRESULT_HASUPDATE) {
                        hasUpdate = true;
                        fList.addAll(list);
                        Log4an.i(logTag, "神马书籍：有更新：" + list.size());
                    } else {
                        Log4an.i(logTag, "神马书籍：无更新");
                    }
                    
                    boolean isAllSuccess = (yisouCheckType==CheckBookMarkUpdate.TYPE_CHECKRESULT_HASUPDATE
                            ||yisouCheckType==CheckBookMarkUpdate.TYPE_CHECKRESULT_NONE
                            ||yisouCheckType==CheckBookMarkUpdate.TYPE_CHECKRESULT_NOMARK)&&
                            (shuqiCheckType==CheckBookMarkUpdate.TYPE_CHECKRESULT_HASUPDATE
                            ||shuqiCheckType==CheckBookMarkUpdate.TYPE_CHECKRESULT_NONE
                            ||shuqiCheckType==CheckBookMarkUpdate.TYPE_CHECKRESULT_NOMARK);
                    
                    if (hasUpdate) {
                        linstener.onFinish(isAllSuccess, TYPE_CHECKRESULT_HASUPDATE, fList);
                    } else {
                        linstener.onFinish(isAllSuccess, TYPE_CHECKRESULT_NONE, null);
                    }
                    if(isAllSuccess){
                        Log4an.i(logTag, "*** 全部检查完成  ***");
                    }
                    isChecking = false;
                    hasUpdate = false;
                    shuqiCheckType = TYPE_CHECKRESULT_NONE;
                    yisouCheckType = TYPE_CHECKRESULT_NONE;
                }
            };
            // 1.先执行书旗的检查更新
            CheckLinstener linstener1 = new CheckLinstener() {
                @Override
                public void onFinish(int resultType, List<CheckBookUpdateInfo> list) {
                    shuqiCheckType = resultType;
                    if (list != null && list.size() > 0
                            && resultType == CheckBookMarkUpdate.TYPE_CHECKRESULT_HASUPDATE) {
                        hasUpdate = true;
                        fList.addAll(list);
                        Log4an.i(logTag, "书旗书籍：有更新：" + list.size());
                    } else {
                        Log4an.i(logTag, "书旗书籍：无更新");
                    }
                    checkBookMarkUpdateFormSM(applicationContext, userId,
                            linstener2);
                }
            };
            checkBookMarkUpdateFormSQ(applicationContext, userId, linstener1);
        } else {
            Log4an.i(logTag, "游客身份，不检查更新");
            linstener.onFinish(false, TYPE_CHECKRESULT_NONE, null);
        }
    }


    /**
     * 检查书籍更新：神马书签
     */
    private void checkBookMarkUpdateFormSM(final Context context, String uid,
            CheckLinstener linstener) {
        synchronized (CheckBookMarkUpdate.class) {
            // List<BookMarkInfo> bookMarks = getTestBookMarks(false);
            List<BookMarkInfo> bookMarks =
                    BookMarkInfoDao.getInstance().getUpdateBookMarkList(uid,
                            BookMarkInfoDao.SYN_TYPE_SHENMA, CHECKMARKNUM_SHENMA);
            if (bookMarks == null || bookMarks.size() < 1) {
                if (linstener != null) {
                    linstener.onFinish(TYPE_CHECKRESULT_NOMARK, null);
                }
                Log4an.d(logTag, "shenma bookMark none");
                return;
            }
            Log4an.d(logTag, "shenma bookMark " + bookMarks.size());
            StringBuffer bids = new StringBuffer();
            StringBuffer oids = new StringBuffer();
            StringBuffer srcs = new StringBuffer();
            for (int i = 0; i < bookMarks.size(); i++) {
                // 书籍更新状态：1:连载、2:完结、3:暂停 || 此书收费模式(0:免费、1:全本收费、2:按章收费、3：全本免费)
                // if ("1".equals(bookMarks.get(i).getStatus()) &&
                // "2".equals(bookMarks.get(i).getPayMode())) {}
                String bookId = bookMarks.get(i).getBookId();
                int oidMax = bookMarks.get(i).getTotalChapter();
                String src = bookMarks.get(i).getSourceId();
                if(oidMax>0){
                    if (i == bookMarks.size() - 1) {
                        bids.append(bookId);
                        oids.append(oidMax);
                        srcs.append(src);
                    } else {
                        bids.append(bookId + "_");
                        oids.append(oidMax + "_");
                        srcs.append(src + "_");
                    }
                }
            }
            checkUpdateSMOnline(context, uid, bids.toString(), oids.toString(), srcs.toString(),
                    linstener);
        }
    }

    /**
     * 检查神马书签更新
     * 
     * @param bookIds bookId1_bookId2...
     * @param oIds oId1_oId2...
     * @return
     */
    private void checkUpdateSMOnline(final Context context, final String userId,
            final String bookIds, final String oIds, final String sourceIds,
            final CheckLinstener linstener) {
        if (TextUtils.isEmpty(bookIds) || bookIds.length() < 2 || TextUtils.isEmpty(oIds)
                || oIds.length() < 2) {
            if (linstener != null) {
                linstener.onFinish(TYPE_CHECKRESULT_NOMARK, null);
            }
            return;
        }
        Log4an.d(logTag, "update bookIds=" + bookIds + ", oids=" + oIds);
        HttpRequestListener httpRequestListener = new HttpRequestListener() {
            @Override
            public List<BasicNameValuePair> setParams() {
                return null;
            }

            @Override
            public String getRequestUrl() {
                return Urls.getCheckBooksUpdateShenMaUrl(bookIds, oIds, sourceIds);
            }

            @Override
            public void action(int actionCode, Object object) {
                if (actionCode == EventTypeConstants.EVENT_SUCCESS) {
                    List<CheckBookUpdateInfo> list = (ArrayList<CheckBookUpdateInfo>) object;
                    if (list != null && list.size() > 0) {
                        onCheckUpdateSuccess(false, list, userId);
                        if (linstener != null) {
                            linstener.onFinish(TYPE_CHECKRESULT_HASUPDATE, list);
                        }
                    } else {
                        if (linstener != null) {
                            linstener.onFinish(TYPE_CHECKRESULT_NONE, null);
                        }
                    }
                } else if (actionCode == EventTypeConstants.EVENT_EXC_PARSER) {
                    Log4an.d(logTag, "check err 解析失败" + actionCode);
                    if (linstener != null) {
                        linstener.onFinish(TYPE_CHECKRESULT_NETERROR, null);
                    }
                } else {// 否则通知失败
                    if (linstener != null) {
                        linstener.onFinish(TYPE_CHECKRESULT_NETERROR, null);
                    }
                    Log4an.d(logTag, "check err 其他失败" + actionCode);
                }
            }
        };
        HttpRequest request =
                new HttpRequest(context, UrlManager.COLUMN_DOMAIN_SEARCH,
                        httpRequestListener.getRequestUrl(), httpRequestListener.setParams(),
                        httpRequestListener);
        request.setDataParseAdapter(new CheckBooksUpdateSMPaser());
        MyTask.runInBackground(request, true);
    }

    /**
     * 检查更新:书旗书签
     */
    private void checkBookMarkUpdateFormSQ(final Context context, String uid,
            CheckLinstener linstener) {
        synchronized (CheckBookMarkUpdate.class) {
            // List<BookMarkInfo> bookMarks = getTestBookMarks(true);
            List<BookMarkInfo> bookMarks =
                    BookMarkInfoDao.getInstance().getUpdateBookMarkList(uid,
                            BookMarkInfoDao.SYN_TYPE_SHUQI, CHECKMARKNUM_SHUQI);
            Map<String, String> ids = new HashMap<String, String>();
            if(bookMarks!=null && bookMarks.size()>0){
                List<String> bookIds = new ArrayList<String>();
                for (BookMarkInfo bookMarkInfo : bookMarks) {
                    bookIds.add(bookMarkInfo.getBookId());
                }
                List<BookInfo> bookInfos = BookInfoDao.getInstance().getBookInfoOfShuqiBookMark(uid, bookIds);
                if(bookInfos!=null && bookInfos.size()>0){
                    for (BookInfo bookInfo : bookInfos) {
                        ids.put(bookInfo.getBookId(), bookInfo.getBookPayMode()+"");
                    }
                }
            }
            if (bookMarks == null || bookMarks.size() < 1) {
                if (linstener != null) {
                    linstener.onFinish(TYPE_CHECKRESULT_NOMARK, null);
                }
                Log4an.d(logTag, "shuqi bookMark none");
                return;
            }
            Log4an.d(logTag, "shuqi bookMark " + bookMarks.size());
            StringBuffer bids = new StringBuffer();
            StringBuffer oids = new StringBuffer();
            StringBuffer payModes = new StringBuffer();
            for (int i = 0; i < bookMarks.size(); i++) {
                // 书籍更新状态：1:连载、2:完结、3:暂停 || 此书收费模式(0:免费、1:全本收费、2:按章收费、3：全本免费)
                // if ("1".equals(bookMarks.get(i).getStatus()) &&
                // "2".equals(bookMarks.get(i).getPayMode())) {}
                String bookId = bookMarks.get(i).getBookId();
                int oidMax = bookMarks.get(i).getTotalChapter();
                if(oidMax>0){
                    if (i == bookMarks.size() - 1) {
                        bids.append(bookId);
                        oids.append(oidMax);
                        payModes.append(ids.get(bookId)==null?"-1":ids.get(bookId));
                    } else {
                        bids.append(bookId + "_");
                        oids.append(oidMax + "_");
                        payModes.append((ids.get(bookId)==null?"-1":ids.get(bookId)) + "_");
                    }
                }
            }
            checkUpdateSQOnline(context, uid, bids.toString(), oids.toString(), payModes.toString(), linstener);
        }
    }

    /**
     * 联网检查书旗书签更新
     */
    private void checkUpdateSQOnline(final Context context, final String userId,
            final String bookIds, final String maxOIds,final String payModes, final CheckLinstener linstener) {
        Log4an.d(logTag, "update userId=" + userId + ",bookIds=" + bookIds + ", oids=" + maxOIds+", payModes="+payModes);
        if (TextUtils.isEmpty(bookIds) || TextUtils.isEmpty(maxOIds)) {
            if (linstener != null) {
                linstener.onFinish(TYPE_CHECKRESULT_NOMARK, null);
            }
            Log4an.d(logTag, " bookIds oids is error");
            return;
        }
        HttpRequestListener httpRequestListener = new HttpRequestListener() {
            @Override
            public List<BasicNameValuePair> setParams() {
                List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
                String timestamp = String.valueOf(System.currentTimeMillis());
                String strTimestamp = timestamp + userId;
                String md5_key = Util.MD5(LoginHelper.Encrypt(strTimestamp));
                params.add(new BasicNameValuePair("PostTime", timestamp));// 时间戳
                params.add(new BasicNameValuePair("PostToken", md5_key));// md5
                params.add(new BasicNameValuePair("maxOids", maxOIds));
                params.add(new BasicNameValuePair("bookIds", bookIds));
                params.add(new BasicNameValuePair("payModes", payModes));
                return params;
            }

            @Override
            public String getRequestUrl() {
                return Urls.getCheckBooksUpdateShuQiUrl();
            }

            @Override
            public void action(int actionCode, Object object) {
                if (actionCode == EventTypeConstants.EVENT_SUCCESS) {
                    List<CheckBookUpdateInfo> list = (ArrayList<CheckBookUpdateInfo>) object;
                    if (list != null && list.size() > 0) {
                        onCheckUpdateSuccess(true, list, userId);
                        if (linstener != null) {
                            linstener.onFinish(TYPE_CHECKRESULT_HASUPDATE, list);
                        }
                    } else {
                        if (linstener != null) {
                            linstener.onFinish(TYPE_CHECKRESULT_NONE, null);
                        }
                    }
                } else if (actionCode == EventTypeConstants.EVENT_EXC_PARSER) {
                    Log4an.d(logTag, "check err 解析失败" + actionCode);
                    if (linstener != null) {
                        linstener.onFinish(TYPE_CHECKRESULT_NETERROR, null);
                    }
                } else {// 否则通知失败
                    if (linstener != null) {
                        linstener.onFinish(TYPE_CHECKRESULT_NETERROR, null);
                    }
                    Log4an.d(logTag, "check err 其他失败" + actionCode);
                }
            }
        };
        HttpRequest request =
                new HttpRequest(context, UrlManager.COLUMN_DOMAIN_READ,
                        httpRequestListener.getRequestUrl(), httpRequestListener.setParams(),
                        httpRequestListener);
        request.setDataParseAdapter(new CheckBooksUpdateSQPaser());
        MyTask.runInBackground(request, true);
    }


    /**
     * 书籍检查更新完毕后保存数据库
     * 
     * @param isShuqi true:书旗书签，false:一搜书签
     * @param list 有更新的书籍数据
     */
    private void onCheckUpdateSuccess(boolean isShuqiBookMark,
            List<CheckBookUpdateInfo> list, String userId) {
        if (list == null || list.size() < 1) {
            Log4an.i(logTag, "书籍检查更新完毕 :none update");
            return;
        }
        Log4an.i(logTag, isShuqiBookMark ? "shuqi" : "shenma" + ("onCheckUpdateSuccess list size = "
                + list.size() + ",userId=" + userId));
        BookMarkInfoDao.getInstance().updateBookMark(userId, list);

        //更新书籍信息表，提醒需要更新目录
        List<String> bookIds = new ArrayList<String>();
        for (CheckBookUpdateInfo checkBookUpdateInfo : list) {
            bookIds.add(checkBookUpdateInfo.getBookId());
        }
        int num = BookInfoDao.getInstance().callBookCatalogNeedUpdate(userId, bookIds,isShuqiBookMark);
        Log4an.i(logTag, "update book_info num = "+num);
    }

    /** 书签检查更新结果回调接口:类内部使用 */
    private interface CheckLinstener {
        /**
         * 书签检查更新结果回调接口
         * 
         * @param resultType 结果返回值
         * @param list 返回成功时有更新的书签
         */
        public void onFinish(int resultType, List<CheckBookUpdateInfo> list);
    }
    /** 书签检查更新结果回调接口 */
    public interface CheckBookMarkUpdateLinstener {
        /**
         * 书签检查更新结果回调接口
         * 
         * @param isAllSuccess 全部检查成功：神马书籍 + 书旗书籍
         * @param resultType 结果返回值
         * @param list 返回成功时有更新的书签
         */
        public void onFinish(boolean isAllSuccess, int resultType, List<CheckBookUpdateInfo> list);
    }
}
